package com.nhh.v.service;

import com.github.pagehelper.PageHelper;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
import com.nhh.exception.ServiceException;
import com.nhh.v.mapper.*;
import com.nhh.v.model.*;
import com.nhh.v.utils.DateUtils;
import com.nhh.v.utils.UUIDUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * User: Allen.qin
 * Date: 2018/9/4
 */
@Service
@Transactional
public class GameService {

    @Autowired
    private NhhwakGamesMapper nhhwakGamesMapper;

    @Autowired
    private NhhwakArticlesMapper nhhwakArticlesMapper;

    @Autowired
    private NhhwakUsersMapper nhhwakUsersMapper;

    @Autowired
    private NhhwakConfigMapper nhhwakConfigMapper;

    @Autowired
    private NhhwakPlaygameDetailsMapper nhhwakPlaygameDetailsMapper;

    @Autowired
    private NhhwakHashrateDetailsMapper nhhwakHashrateDetailsMapper;

    @Autowired
    private NhhwakTownsMapper nhhwakTownsMapper;

    @Autowired
    private NhhwakCollectGamesMapper nhhwakCollectGamesMapper;

    public Map<String, Object> getArticle(String articleId, String category) {

        NhhwakArticles articles = null;
        if (!StringUtils.isEmpty(articleId)) {
            articles = nhhwakArticlesMapper.getOne(articleId);
        } else if (!StringUtils.isEmpty(category)) {
            articles = nhhwakArticlesMapper.getOneByCategory(category);
        }
        if (articles == null) {
            articles = NhhwakArticles.builder().title("内容不存在").content("对不起，你访问的内容不存在").build();
        }
        if (articles.getContent().trim().length() < 5) {
            articles.setContent("<div style=\"text-align:center;font-size:2rem;line-height:3rem;\">敬请期待...</div>");
        }
        HashMap<String, Object> resultData = Maps.newHashMap();
        resultData.put("article", articles);
        return resultData;
    }

    public boolean collect(Integer uid, Integer gameId) {
        NhhwakCollectGames collectGames = NhhwakCollectGames.builder().userId(uid).gameId(gameId).build();
        int count = nhhwakCollectGamesMapper.selectCount(collectGames);
        int result;
        if (count > 0) {
            result = nhhwakCollectGamesMapper.delete(collectGames);
        } else {
            collectGames.setStatus(true);
            result = nhhwakCollectGamesMapper.insert(collectGames);
        }
        return result > 0;
    }

    public Map<String, Object> executeGameEnd(String playUid) {
        Preconditions.checkArgument(!StringUtils.isEmpty(playUid), "playUid is empty.");

        NhhwakPlaygameDetails playgameDetails = nhhwakPlaygameDetailsMapper.selectOne(NhhwakPlaygameDetails.builder().playUid(playUid).build());

        if (playgameDetails == null ||
                playgameDetails.getUserId() == null ||
                playgameDetails.getGameId() == null) {
            throw new ServiceException("15002", "游戏记录不存在！");
        }

        if (playgameDetails.getEndtime() != null) {
            throw new ServiceException("15005", "游戏算力已获得！");
        }

        int userCount = nhhwakUsersMapper.selectCount(NhhwakUsers.builder().id(playgameDetails.getUserId()).build());
        if (userCount == 0) {
            throw new ServiceException("15003", "用户不存在！");
        }
        int gameCount = nhhwakGamesMapper.selectCount(NhhwakGames.builder().id(playgameDetails.getGameId()).build());
        if (gameCount == 0) {
            throw new ServiceException("15004", "游戏不存在！");
        }

        Date endTime = new Date();
        nhhwakPlaygameDetailsMapper.updateEndTime(playgameDetails.getPlayUid(), endTime);

        NhhwakConfig config = nhhwakConfigMapper.getHashRateConfig();
        Long periodNum = 0L;
        if (config == null) {
            throw new ServiceException("9999", "配置信息缺失！");
        }
        Long maxHashRate = config.getGameMaxHashrate() == null ? 0 : config.getGameMaxHashrate();
        Long perHashRate = config.getGamePerHashrate() == null ? 0 : config.getGamePerHashrate();
        Integer hashRateDuration = config.getGameHashrateDuration() == null ? 0 : config.getGameHashrateDuration();
        if (hashRateDuration > 0) {
            periodNum = DateUtils.between(playgameDetails.getStarttime(), endTime) / hashRateDuration;
        }
        Long factGameHashrate;
        if (periodNum <= 0) {
            factGameHashrate = fn_getGameHashrate(playgameDetails.getUserId(), maxHashRate, perHashRate, 1L);
        } else {
            factGameHashrate = fn_getGameHashrate(playgameDetails.getUserId(), maxHashRate, perHashRate, periodNum);
        }
        Long gameHashRate = 0L;
        if (periodNum > 0) {
            gameHashRate = factGameHashrate;

            if (gameHashRate > 0) {
                //todo user add version
                nhhwakUsersMapper.updateHashRateById(playgameDetails.getUserId(), gameHashRate);
                nhhwakHashrateDetailsMapper.insert(
                        NhhwakHashrateDetails.builder().
                                userId(playgameDetails.getUserId()).hashrate(gameHashRate).
                                relateId(playgameDetails.getGameId()).playId(playgameDetails.getId()).
                                source("game").build());
                //todo towns add version
                nhhwakTownsMapper.updateTempHashRateByUserId(playgameDetails.getUserId(), gameHashRate);

                //todo Invite
            }
        }

        Long dayHashrate = nhhwakHashrateDetailsMapper.getHashRateByUserId(playgameDetails.getUserId());
        HashMap<String, Object> resultData = Maps.newHashMap();
        resultData.put("gameHashrate", gameHashRate);
        resultData.put("factGameHashrate", factGameHashrate);
        resultData.put("dayHashrate", dayHashrate);
        resultData.put("gameMaxHashrate", maxHashRate);
        return resultData;
    }

    private Long fn_getGameHashrate(Integer userID, Long maxHashRate, Long perHashrate, Long periodNum) {
        Preconditions.checkArgument(perHashrate > 0 && maxHashRate > 0 && periodNum > 0, "[maxHashRate/maxHashRate/periodNum] param error");
        Long hashRate = nhhwakHashrateDetailsMapper.getHashRateByUserId(userID);

        hashRate = hashRate == null ? 0 : hashRate;
        if (maxHashRate >= (hashRate + perHashrate * periodNum)) {
            hashRate = perHashrate * periodNum;
        } else {
            hashRate = maxHashRate - hashRate;
        }
        return hashRate;
    }

    public Map<String, Object> executeGameStart(Integer userId, Integer gameId) {
        Preconditions.checkArgument(userId != null, "userId is empty.");
        Preconditions.checkArgument(gameId != null, "userId is empty.");

        int userCount = nhhwakUsersMapper.selectCount(NhhwakUsers.builder().id(userId).build());
        if (userCount == 0) {
            throw new ServiceException("14003", "用户不存在！");
        }
        int gameCount = nhhwakGamesMapper.selectCount(NhhwakGames.builder().id(gameId).build());
        if (gameCount == 0) {
            throw new ServiceException("14004", "游戏不存在！");
        }

        String playUid = UUIDUtils.generateUUID();
        nhhwakPlaygameDetailsMapper.insert(
                NhhwakPlaygameDetails
                        .builder()
                        .playUid(playUid).userId(userId).gameId(gameId).starttime(new Date()).build()
        );

        NhhwakConfig config = nhhwakConfigMapper.getHashRateConfig();
        Long maxHashRate = config.getGameMaxHashrate() == null ? 0 : config.getGameMaxHashrate();
        Long perHashRate = config.getGamePerHashrate() == null ? 0 : config.getGamePerHashrate();
        Long gameHashRate = fn_getGameHashrate(userId, maxHashRate, perHashRate, 1L);

        //todo add version
        nhhwakGamesMapper.updateClickCount(gameId);

        HashMap<String, Object> resultData = Maps.newHashMap();
        resultData.put("playUid", playUid);
        resultData.put("gameHashrate", gameHashRate);
        resultData.put("maxHashrate", maxHashRate);
        return resultData;

    }

    public void executeSwitchIn(String playUid) {
        Preconditions.checkArgument(!StringUtils.isEmpty(playUid), "playUid is empty.");
        nhhwakPlaygameDetailsMapper.updateSwitchInTime(playUid);
    }

    public void executeSwitchOut(String playUid) {
        Preconditions.checkArgument(!StringUtils.isEmpty(playUid), "playUid is empty.");
        nhhwakPlaygameDetailsMapper.updateSwitchOutTime(playUid);
    }


    public Map<String, Object> queryGames(Long userId, String pIndex, String pSize) {
        Map<String, Object> data = Maps.newHashMap();
        PageHelper.startPage(Integer.valueOf(pIndex), Integer.valueOf(pSize));
        data.put("rows", nhhwakGamesMapper.queryGames());

        data.put("dayHashrate", nhhwakGamesMapper.getDayGameHashrate(userId));
        data.put("banners", convent(nhhwakArticlesMapper.queryBanners()));
        data.put("subBanners", convent(nhhwakArticlesMapper.querySubBanners()));
        return data;
    }

    /**
     * 替换内容
     *
     * @param articlesList
     * @return
     */
    private List convent(List<NhhwakArticles> articlesList) {
        Preconditions.checkArgument(articlesList != null, "articlesList is null.");

        for (int i = 0; i < articlesList.size(); i++) {
            NhhwakArticles articles = articlesList.get(i);

            articles.setIcon(this.getMidImgUrl(articles.getIcon()));
            if (articles.getImgUrls() != null) {
                articles.setImgUrls(this.getMidImgUrl(articles.getImgUrls().split(",")[0]));
            }
            if (articles.getOuterLink() != null) {
                articles.setOuterLink(this.getMidImgUrl(articles.getOuterLink()));
            }
            if (articles.getContent() != null) {
                articles.setContent(articles.getContent().trim());
            }
            articlesList.set(i, articles);
        }
        return articlesList;
    }

    private static final String NHH_HOME_URL = "http://nwk.bitgm.com";

    /**
     * 拼接url
     *
     * @param url
     * @return
     */
    private String getMidImgUrl(String url) {
        Preconditions.checkArgument(url != null, "url is null");

        List<String> splitUrls = Splitter.on("/").trimResults().splitToList(url);
        String file = splitUrls.get(splitUrls.size() - 1);
        String prefixUrl = Joiner.on("/").join(splitUrls.subList(0, splitUrls.size() - 1));

        return (url.toLowerCase().indexOf("http") > 0 ? "" : NHH_HOME_URL) + prefixUrl + "_thumbs/" + file;
    }

}
